package com.lianxi.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.lianxi.exacl.world.MyIImageExtractor;
import com.lianxi.util.StringUtil;
import fr.opensagres.poi.xwpf.converter.core.BasicURIResolver;
import fr.opensagres.poi.xwpf.converter.core.ImageManager;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.poi.POIXMLTextExtractor;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.*;

/**
 * Created by wjn
 * Date 2018/4/9
 *
 * @author wen
 */
public class PoiUtil2 {
    /**
     * Word 2007以上
     *
     * @param filePath 文件绝对路径
     * @return word内容
     */
    public static String readDocx(String filePath) {
        try {
            FileInputStream fis = new FileInputStream(new File(filePath));
            XWPFDocument document = new XWPFDocument(fis);
            XWPFWordExtractor extractor = new XWPFWordExtractor(document);
            fis.close();
            return extractor.getText();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String readDocx(FileInputStream fis) {
        try {
            XWPFDocument document = new XWPFDocument(fis);
            XWPFWordExtractor extractor = new XWPFWordExtractor(document);
            fis.close();

            return extractor.getText();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }


    /**
     * Word 97 - Word 2003
     *
     * @param filePath 文件绝对路径
     * @return word内容
     */
    public static String readDoc(String filePath) {
        try {
            FileInputStream fis = new FileInputStream(new File(filePath));
            HWPFDocument document = new HWPFDocument(fis);
            WordExtractor extractor = new WordExtractor(document);
            fis.close();
            return extractor.getText();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Word 97 - Word 2003
     *
     * @param inputStream 文件流
     * @return word内容
     */
    public static String readDoc(InputStream inputStream) {
        try {
            HWPFDocument document = new HWPFDocument(inputStream);
            WordExtractor extractor = new WordExtractor(document);
            inputStream.close();
            return extractor.getText();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }


    //**********************我的开始*********************
    public static List<String> searchWordDocX(InputStream inputStream) {
        //读取文件路径
        String content = null;
        List<String> docxList = new ArrayList<String>();
        try {
            XWPFDocument xwpf = new XWPFDocument(inputStream);
            POIXMLTextExtractor poiText = new XWPFWordExtractor(xwpf);
            content = poiText.getText();
            docxList.add(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return docxList;
    }


    public static List<String> doDocx(FileInputStream is) {
        //用于存放预览信息
        List<String> list = new ArrayList<String>();
        try {

            //获取文件对象
            XWPFDocument doc = new XWPFDocument(is);
            //获取文件内容对象
            XWPFParagraph[] paras = doc.getParagraphs().toArray(new XWPFParagraph[0]);
            String tempTitle = null;
            for (XWPFParagraph graph : paras) {
                //获取所有的表格对象
                List tables = doc.getTables();
                //因我文档中只有一个所以这里没有去遍历，直接获取指定表格对象
                XWPFTable table = (XWPFTable) tables.get(0);
                //迭代行，默认从0开始
                for (int j = 0; j < table.getRows().size(); j++) {
                    //当前行
                    XWPFTableRow tr = table.getRow(j);
                    //用于存放一行数据，不需要可以不用
                    String rowText = "";
                    //迭代列，默认从0开始
                    for (int x = 0; x < tr.getTableCells().size(); x++) {
                        //取得单元格
                        XWPFTableCell td = tr.getCell(x);
                        //取得单元格的内容
                        String text = td.getText();
                        //自己用“ ”区分两列数据，根据自己需求 可以省略
                        if (StringUtil.isEmpty(rowText)) {
                            rowText = text;
                        } else {
                            rowText = rowText + " " + text;
                        }
                    }
                    list.add(rowText);
                }
            }
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }


    public static String readDocx2(FileInputStream fis) {
        try {
            XWPFDocument document = new XWPFDocument(fis);
            XWPFWordExtractor extractor = new XWPFWordExtractor(document);
            List<XWPFTable> tables = document.getTables();
            fis.close();
            return extractor.getText();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }


    /**
     * 将docx文件转成html.
     * <p>
     *
     * @param inputStream docx文件流.
     * @return String
     * @Title: docxToHtml
     * </p>
     * <p>
     * @Description: </p>
     */
    public static String docxToHtml(InputStream inputStream) {
        String docxContent = null;
        OutputStreamWriter out = null;
        File file = null;
        try {
            file = new File("E:\\Desktop\\素材\\world素材.html");
            final String filePath = file.getPath();
            // 读取docx文档
            XWPFDocument document = new XWPFDocument(inputStream);

            // 输出docx文档
            XHTMLOptions options = XHTMLOptions.create();
            options.setIgnoreStylesIfUnused(false);
            options.setFragment(true);
            out = new OutputStreamWriter(new FileOutputStream(filePath), "UTF-8");
            XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();
            xhtmlConverter.convert(document, out, options);

//            docxContent = readfile(filePath);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return docxContent;
    }


    public static File docxConvert(String parentDirectory, String filename, String newName) {
        parentDirectory = "E:\\Desktop\\";
        filename = "E:\\Desktop\\素材\\world素材.docx";
        newName = "123";
        try {
            XWPFDocument document = new XWPFDocument(new FileInputStream(filename));
            XHTMLOptions options = XHTMLOptions.create().setImageManager(new ImageManager(new File(parentDirectory), UUID.randomUUID().toString())).indent(4);
            FileOutputStream out = new FileOutputStream(new File(parentDirectory + newName + ".html"));
            XHTMLConverter.getInstance().convert(document, out, options);
            return new File(parentDirectory + newName + ".html");
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
    }


    public static String docToHtml() throws Exception {
        File path = new File("E:\\Desktop\\");
        String imagePathStr = path.getAbsolutePath() + "\\素材\\image\\";
        String sourceFileName = path.getAbsolutePath() + "\\素材\\world素材.docx";
        String targetFileName = path.getAbsolutePath() + "\\素材\\test2.html";
        File file = new File(imagePathStr);
        if (!file.exists()) {
            file.mkdirs();
        }
        HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(sourceFileName));
        org.w3c.dom.Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document);
        //保存图片，并返回图片的相对路径
        wordToHtmlConverter.setPicturesManager((content, pictureType, name, width, height) -> {
            try (FileOutputStream out = new FileOutputStream(imagePathStr + name)) {
                out.write(content);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "image/" + name;
        });
        wordToHtmlConverter.processDocument(wordDocument);
        org.w3c.dom.Document htmlDocument = wordToHtmlConverter.getDocument();
        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(new File(targetFileName));
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer serializer = tf.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        serializer.transform(domSource, streamResult);
        return targetFileName;
    }


    public static String docxToHtml() throws Exception {
        File path = new File("E:\\Desktop\\");
        String imagePath = path.getAbsolutePath() + "\\素材\\image\\";
        String sourceFileName = path.getAbsolutePath() + "\\素材\\world素材.docx";
        String targetFileName = path.getAbsolutePath() + "\\素材\\test3.html";
        OutputStreamWriter outputStreamWriter = null;
        try {
            XWPFDocument document = new XWPFDocument(new FileInputStream(sourceFileName));
            XHTMLOptions options = XHTMLOptions.create();
            // 存放图片的文件夹,存放图片的路径
//            options.setExtractor(new FileImageExtractor(new File(imagePath)));
            String s = IdUtil.simpleUUID();
            options.setExtractor(new MyIImageExtractor(s));
            // html中图片的路径
            options.URIResolver(new BasicURIResolver("https://t1file.dahe.cn/" + s + "/"));
            outputStreamWriter = new OutputStreamWriter(new FileOutputStream(targetFileName), "utf-8");
            XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();
            xhtmlConverter.convert(document, outputStreamWriter, options);
        } finally {
            if (outputStreamWriter != null) {
                outputStreamWriter.close();
            }
        }
        return targetFileName;
    }


    public static String docxToHtml2() {
        File path = new File("E:\\Desktop\\");
        String sourceFileName = path.getAbsolutePath() + "\\素材\\空.docx";
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        //图片老路径与新路径关系
        HashMap<String, String> map = new HashMap<>();
        String strHtml = new String();
        try {
            XWPFDocument document = new XWPFDocument(new FileInputStream(sourceFileName));
            XHTMLOptions options = XHTMLOptions.create();
            // 存放图片的文件夹,存放图片的路径
            options.setExtractor(new MyIImageExtractor(map));
            // html中图片的路径
            options.URIResolver(new BasicURIResolver(""));
            XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();
            xhtmlConverter.convert(document, out, options);
            strHtml = replaceImageSrc(new String(out.toByteArray()), map);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return strHtml;
    }

    public static String docToHtml2() throws Exception {
        File path = new File("E:\\Desktop\\");
        String sourceFileName = path.getAbsolutePath() + "\\素材\\在我们的生活中.doc";
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(sourceFileName));
        org.w3c.dom.Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document);
        //保存图片，并返回图片的相对路径
        wordToHtmlConverter.setPicturesManager((content, pictureType, name, width, height) -> {
            return "data:image/jpeg;base64," + Base64.getEncoder().encodeToString(content);
        });
        wordToHtmlConverter.processDocument(wordDocument);
        org.w3c.dom.Document htmlDocument = wordToHtmlConverter.getDocument();
        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(byteArrayOutputStream);
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer serializer = tf.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        serializer.transform(domSource, streamResult);
        return StringEscapeUtils.unescapeHtml4(new String(byteArrayOutputStream.toByteArray()));
    }



    public static void main(String[] args) throws Exception {
//        docToHtml2();

        FileUtil.writeString(docxToHtml2(),"E:\\Desktop\\xxxxdemo.html","utf-8");
    }

    //替换图片路径
    public static String replaceImageSrc(String strHtml, Map<String, String> map) {
        Document document = Jsoup.parse(StringEscapeUtils.unescapeHtml4(strHtml));
        Elements imgElements = document.getElementsByTag("img");
        for (Element imgElement : imgElements) {
            String newsrc = map.get(imgElement.attr("src"));
            imgElement.attr("src", "data:image/jpeg;base64," + newsrc);
        }
        return document.toString();
    }


}



